﻿using Microsoft.Maps.MapControl.WPF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using TrailMapManager.Common;
using TrailMapManager.Common.Poi;

namespace TrailMapManager.Modules.Poi.Logic
{
    public class PoiMainViewLogic : BaseViewLogic
    {
        public PoiManager PoiMan
        {
            get
            {
                return PoiManager.Instance;
            }
        }

        private PoiPoint _selectedPoi;
        public PoiPoint SelectedPoi
        {
            get { return _selectedPoi; }
            set
            {
                _selectedPoi = value;
                NotifyPropertyChanged("SelectedPoi");
                NotifyPropertyChanged("PushpinVisible");
                if (value != null)
                {
                    SelectedLatitude = value.Position.Latitude.ToString();
                    SelectedLongitude = value.Position.Longitude.ToString();
                }
                MoveCenterLittleBit();
            }
        }

        private string _selectedLongitude;
        public string SelectedLongitude
        {
            get { return _selectedLongitude; }
            set
            {
                _selectedLongitude = value;
                double newLong = 0;
                if (double.TryParse((string)value, out newLong))
                {
                    if (SelectedPoi != null)
                    {
                        SelectedPoi.Position.Longitude = newLong;
                    }
                }
                NotifyPropertyChanged("SelectedLongitude");
            }
        }

        private string _selectedLatitude;
        public string SelectedLatitude
        {
            get { return _selectedLatitude; }
            set
            {
                _selectedLatitude = value;
                double newLat = 0;
                if (double.TryParse((string)value, out newLat))
                {
                    if (SelectedPoi != null)
                    {
                        SelectedPoi.Position.Latitude = newLat;
                    }
                }
                NotifyPropertyChanged("SelectedLatitude");
            }
        }

        public Visibility PushpinVisible
        {
            get
            {
                if (SelectedPoi == null)
                {
                    return Visibility.Collapsed;
                }
                else
                {
                    return Visibility.Visible;
                }
            }
        }

        private Location _mapCenter;
        public Location MapCenter
        {
            get { return _mapCenter; }
            set { _mapCenter = value; NotifyPropertyChanged("MapCenter"); }
        }

        private RelayCommand _newPoiCommand;
        public RelayCommand NewPoiCommand
        {
            get
            {
                if (_newPoiCommand == null)
                {
                    _newPoiCommand = new RelayCommand(
                        () =>
                        {
                            NewPoi();
                        });
                }
                return _newPoiCommand;
            }
        }

        private RelayCommand _savePoiCommand;
        public RelayCommand SavePoiCommand
        {
            get
            {
                if (_savePoiCommand == null)
                {
                    _savePoiCommand = new RelayCommand(
                        () =>
                        {
                            SavePoi();
                        },
                        () =>
                        {
                            return SelectedPoi != null;
                        });
                }
                return _savePoiCommand;
            }
        }

        private RelayCommand<PoiPoint> _deletePoiCommand;
        public RelayCommand<PoiPoint> DeletePoiCommand
        {
            get
            {
                if (_deletePoiCommand == null)
                {
                    _deletePoiCommand = new RelayCommand<PoiPoint>(
                        poi =>
                        {
                            if (poi != null)
                            {
                                DeletePoi(poi);
                            }
                        },
                        poi =>
                        {
                            return poi != null;
                        });
                }
                return _deletePoiCommand;
            }
        }

        private RelayCommand<PoiPoint> _setPoiLocationCommand;
        public RelayCommand<PoiPoint> SetPoiLocationCommand
        {
            get
            {
                if (_setPoiLocationCommand == null)
                {
                    _setPoiLocationCommand = new RelayCommand<PoiPoint>(
                        poi =>
                        {
                            this.SetPoiLocation(poi);
                        },
                        poi =>
                        {
                            return poi != null;
                        });
                }
                return _setPoiLocationCommand;
            }
        }

        private void SetPoiLocation(PoiPoint poi)
        {
            poi.Position = MapCenter;
        }

        private void SavePoi()
        {
            PoiMan.SavePoiToPhone(SelectedPoi);
        }

        private void NewPoi()
        {
            PoiMan.Points.Add(new PoiPoint()
            {
                Position = MapCenter,
                Name = "New point",
                Description = "",
                Id = Guid.NewGuid(),
            });
        }


        public PoiMainViewLogic()
        {
            MapCenter = new Location();
        }

        private void MoveCenterLittleBit()
        {
            new Task(
                () =>
                {
                    var oldCenter = MapCenter;
                    var newCenter = new Location(MapCenter.Latitude, MapCenter.Longitude + 0.00000000001);
                    InvokeOnMainThread(
                        () =>
                        {
                            MapCenter = newCenter;
                        });
                    Thread.Sleep(10);
                    InvokeOnMainThread(
                        () =>
                        {
                            MapCenter = oldCenter;
                        });
                }).Start();
        }

        private void DeletePoi(PoiPoint poi)
        {
            PoiMan.DeltePoi(poi);
        }
    }

    public class CoordinateValidation : ValidationRule
    {

        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            double newLong = 0;
            if (double.TryParse((string)value, out newLong))
            {
                return new ValidationResult(true, null);
            }
            return new ValidationResult(false, "Invalid Coordinate");
        }
    }
}
